
package com.segment.dcore.dubbo.filter;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.*;

import com.segment.dcore.base.component.ContextIDGenerator;
import com.segment.dcore.base.constants.ServiceConstants;
import com.segment.dcore.base.filter.ServiceFilterRegister;
import com.segment.dcore.base.service.KCoreService;
import com.segment.dcore.base.utils.ContextIdUtil;
import com.segment.dcore.dubbo.enums.InvokeEnum;
import com.segment.dcore.dubbo.filter.context.DubboInvokeContext;

/**
 * dubbo服务调用拦截器
 *
 * Created by huapeng.hhp on 2017/2/26.
 */
@Activate(group = Constants.CONSUMER)
public class ConsumerFilter implements Filter {
	/** 业务执行组件 */
	private KCoreService kcoreService = ServiceFilterRegister
			.getFilterRegisterService(ServiceConstants.DUBBO_FILTER_REGISTER_SERVICE);

	/** 请求ID生成器 */
	private ContextIDGenerator contextIdGenerator = ContextIDGenerator.getContextIDGenerator();

	@Override
	public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
		final DubboInvokeContext invokeContext = new DubboInvokeContext();
		invokeContext.setInv(invocation);
		invokeContext.setInvoker(invoker);
		invokeContext.setInvokeEnum(InvokeEnum.DUBBO_CONSUMER);
		// 生成调用ID和DEPTH并调用服务
		String requestId = invokeContext.getInv().getAttachment(ServiceConstants.INSIGHT_REQUEST_ID);
		String depthStr = invokeContext.getInv().getAttachment(ServiceConstants.INSIGHT_DEPTH);
		String orderStr = invokeContext.getInv().getAttachment(ServiceConstants.INSIGHT_ORDER);
		Integer depth = depthStr == null ? 0 : Integer.valueOf(depthStr);
		Integer order = orderStr == null ? 0 : Integer.valueOf(orderStr);
		return ContextIdUtil.ConsumeContextIdAndDepth(requestId, depth, order, contextIdGenerator,
				new ContextIdUtil.RequestInvoke<Result>() {
					// 调用业务逻辑
					public Result doInvoke(final String requestId, final Integer depth, final Integer order) {
						String entryName = ContextIdUtil.getEntryName();
						// 将调用ID和depth放在上下文中
						invokeContext.getInv().getAttachments().put(ServiceConstants.INSIGHT_REQUEST_ID, requestId);
						invokeContext.getInv().getAttachments().put(ServiceConstants.INSIGHT_DEPTH, depth.toString());
						invokeContext.getInv().getAttachments().put(ServiceConstants.INSIGHT_ORDER, order.toString());
						if (entryName != null) {
							invokeContext.getInv().getAttachments().put(ServiceConstants.INSIGHT_ENTRY, entryName);
						}
						// 调用服务
						kcoreService.doService(invokeContext);
						return invokeContext.getResult();
					}
				});
	}
}
